package com.gitee.feizns.quickstart.web.restful;

import com.gitee.feizns.quickstart.domain.page.PageAo;
import com.gitee.feizns.quickstart.domain.page.PageRecordsVo;
import com.gitee.feizns.quickstart.web.restful.ex.ResourceNotFoundException;

import java.io.Serializable;
import java.util.List;

/**
 * rest式服务
 * @author feizns
 * @since 2023/04/05
 */
public interface RestExecutor {

    /**
     * 验证是否存在编号
     * @param recordType 记录类型
     * @param id 编号
     * @throws ResourceNotFoundException 不存在抛出
     */
    boolean existsId(Class<?> recordType, Serializable id);

    /**
     * 验证是否存在编号
     * @param recordType 记录类型
     * @param id 编号
     * @throws ResourceNotFoundException 不存在抛出
     */
    default void ifNotExistsIdThrow(Class<?> recordType, Serializable id) {
        if ( !existsId(recordType, id) )
            throwsResourceNotFoundException(id);
    }

    /**
     * 引发 Resource Not Found 异常
     * @param id 编号
     */
    default void throwsResourceNotFoundException(Serializable id) {
        throw new ResourceNotFoundException(String.format("数据不存在：编号[%s].", id));
    }

    /**
     * 创建资源
     * @param records 记录
     * @return {@link T}
     */
    <T> List<T> create(Class<T> recordType, Object... records);

    /**
     * 更新通过编号
     * @param id 编号
     * @param recordType 记录类型
     * @return {@link T}
     */
    <T> T putById(Class<T> recordType, Object ao, Serializable id);

    /**
     * 批量新增或更新数据
     * @param recordType 记录类型
     * @param aos 查询请求
     * @return {@link T}
     */
    <T> List<T> put(Class<T> recordType, Object... aos);

    /**
     * 更新通过编号
     * @param record 新增或更新的数据
     * @param id 编号
     * @return {@link T}
     */
    <T> T putById(T record, Serializable id);

    /**
     * 更新通过编号
     * @param record 待更新的数据
     * @param id 编号
     * @return {@link T}
     */
    <T> T patchById(T record, Serializable id);

    /**
     * 批量更新数据
     * @param record 待更新的数据
     * @param ao 查询请求参数
     * @return {@link T}
     */
    <T> long patch(T record, Object ao);

    /**
     * 根据编号删除数据
     * @param recordType 记录类型
     * @param id 编号
     * @return {@link T}
     */
    <T> T deleteById(Class<T> recordType, Serializable id);

    /**
     * 批量删除返回删除的行数
     * @param recordType 记录类型
     * @param ao 查询参数列表
     * @return long
     */
    <T> long delete(Class<T> recordType, Object ao);

    /**
     * 通过编号获取数据
     * @param recordType 记录类型
     * @param id 编号
     * @return {@link T}
     */
    <T> T getById(Class<T> recordType, Serializable id);

    /**
     * 查询分页参数
     * @param recordType 记录类型
     * @param page 分页参数
     * @param aos 参数列表
     * @return {@link PageRecordsVo}<{@link T}>
     */
    <T> PageRecordsVo<T> page(Class<T> recordType, PageAo page, Object... aos);

}
